package main

import (
	"fmt"
	"sync"
)

/**

	channel 例子六：
		接收方，接收完毕的时候，通知发送我接收完毕了！

		使用 Go 语言提供的 sync.WaitGroup 的方式，来等待任务结束处理！之前处理方式比较繁琐

	// 使用 go 语言提供的等待组，等待组
	var wq sync.WaitGroup
	// 表示有多少个任务，比如添加20个任务
	wq.Add(20)
	// 每个任务做完后，在任务做完后调用
	wq.Done()
	// 等待任务做完，在任务开始后调用
	wq.Wait()

 */

 // c 这个chan 表示数据
func donWorker6(id int, c chan int, wg *sync.WaitGroup)  {

	for n := range c {
		fmt.Printf("编号：%d, 接收到数据：%c\n", id, n)
		// 表示我接收完毕这个数据
		wg.Done()
	}

}

// 可以创建一个结构
type worker6 struct {
	in chan int // chan int 表示我这个chan里面的值只能是 int
	wg *sync.WaitGroup
}

// 创建 chan
func createWorker6(id int, wg *sync.WaitGroup) worker6 {
	// 创建 chan
	w := worker6 {
		in: make(chan int), // chan int 表示我这个chan里面的值只能是 int
		wg: wg,
	}
	// 调用协程去接收
	go donWorker6(id, w.in, wg)

	return w
}

func chanDemo6(){
	// 使用 go 语言提供的等待组，等待组
	var wg sync.WaitGroup
	// 表示有多少个任务，比如添加20个任务
	wg.Add(20)
	// 每个任务做完后
	// wq.Done()
	// 等待任务做完
	// wq.Wait()

	// 创建十个大小的 worker6
	var workers [10]worker6

	for i := 0; i< 10 ;i ++  {
		workers[i] = createWorker6(i, &wg)
	}

	// 发送数据
	for i := 0; i < 10 ;i ++  {
		workers[i].in <- 'a' + i
		// 也可以每次 加一，就不用写上面的20了
		// wg.Add(1)
	}

	// 发送数据
	for i := 0; i < 10 ;i ++  {
		workers[i].in <- 'A' + i
		// 也可以每次 加一，就不用写上面的20了
		// wg.Add(1)
	}

	// 等待上面两个for循环，也就是20个任务做完
	wg.Wait()

	/**

		这个例子来实现等待任务结束是最好的办法！用 Go 语言提供的方式

	 */

}

func main() {
	chanDemo6()
	
}
